<!DOCTYPE html>
<script src='../resources/testharness.js'></script>
<script src='../resources/testharnessreport.js'></script>
<script>
'use strict';

const safelist = ['custom-element',
                  'article', 'aside', 'blockquote', 'body', 'div', 'footer',
                  'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
                  'header', 'main', 'nav', 'p', 'section', 'selectmenu', 'span'];

test(() => {
  safelist.forEach((tag) => {
    ['open', 'closed'].forEach((mode) => {
      try {
        const sr = document.createElement(tag).attachShadow({mode: mode});
        assert_true(sr instanceof ShadowRoot, "attachShadow is supported for " + tag);
      } catch (e) {
        assert_unreached("attachShadow is not supported for " + tag);
      }
    });
  });
}, 'attachShadow should not fail for an element in the safelist');

test(() => {
  // Retrieve possible tag names from window object's own property names
  Object.getOwnPropertyNames(window).forEach((p) => {
    const res = /^HTML(.*)Element$/.exec(p);
    if (!res)
      return;
    const maybeTagName = res[1].toLowerCase();
    if (safelist.includes(maybeTagName) || maybeTagName.indexOf('-') != -1)
      return;
    var element;
    try {
      element = document.createElement(maybeTagName);
    } catch (e) {
      // Okay to ignore when document.createElement fails
      return;
    }
    ['open', 'closed'].forEach((mode) => {
      assert_throws_dom('NotSupportedError', () => {
        element.attachShadow({mode: mode});
      }), 'attachShadow should throw NotSupportdeError for ' + maybeTagName;
    });
  });
}, 'attachShadow should throw an exception for an element which is not in the safelist');

test(() => {
  class XFoo extends HTMLElement {
    constructor() {
      super();
    }
  }
  window.customElements.define('x-foo', XFoo);
  assert_true(new XFoo().attachShadow({mode: 'open'}) instanceof ShadowRoot);
}, 'attachShadow should not fail for Custom Elements v1.');
</script>
